/////////////////////////////////////////////////////////////////////////////
// Name:        shortcutcust.h
// Purpose:     Classes for allowing the user to customise shortcuts.
// Author:      Julian Smart
// Modified by:
// Created:     2009-04-13
// RCS-ID:      $Id$
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _WX_SHORTBARCUST_H_
#define _WX_SHORTBARCUST_H_

#include "wx/accel.h"
#include "wx/confbase.h"
#include "wx/dynarray.h"
#include "wx/textctrl.h"

/**
 @class wxShortcutItem
 This class stores customisation information about a single command.
 */

class wxShortcutItem: public wxObject
{
public:
    wxShortcutItem() { Init(); }
    wxShortcutItem(int id, const wxString& name, const wxString& category,
        const wxString& descr, int flags, int keyCode)
    {
        Init();
        m_id = id; 
        m_name = name; 
        m_category = category;
        m_description = descr; 
        m_flags = flags; 
        m_keyCode = keyCode;
    }
    wxShortcutItem(const wxShortcutItem& item) { Copy(item); }
    ~wxShortcutItem() {}

    void Init();

    void Copy(const wxShortcutItem& item, bool excludeId = false);

    bool operator==(const wxShortcutItem& item) const;

    wxShortcutItem& SetId(int id) { m_id = id; return *this; }
    int GetId() const { return m_id; }

    // state
    wxShortcutItem& Enable(bool enable) { m_enabled = enable; return *this; }

    bool IsEnabled() const { return m_enabled; }

    wxShortcutItem& SetName(const wxString& name) { m_name = name; return *this; }
    const wxString& GetName() const { return m_name; }

    wxShortcutItem& SetCategory(const wxString& cat) { m_category = cat; return *this; }
    const wxString& GetCategory() const { return m_category; }

    wxShortcutItem& SetDescription(const wxString& descr) { m_description = descr; return *this; }
    const wxString& GetDescription() const { return m_description; }

    wxShortcutItem& SetFlags(int flags) { m_flags = flags; return *this; }
    int GetFlags() const { return m_flags; }

    wxShortcutItem& SetKeyCode(int keyCode) { m_keyCode = keyCode; return *this; }
    int GetKeyCode() const { return m_keyCode; }

public:

    int                     m_id;
    bool                    m_enabled;
    wxString                m_name;
    wxString                m_category;
    wxString                m_description;
    int                     m_flags;
    int                     m_keyCode;
};

WX_DECLARE_OBJARRAY(wxShortcutItem, wxShortcutItemArray);

/**
 @class wxShortcutManager
 This class stores customisation information for the application.
*/

class wxShortcutManager: public wxObject
{
public:
    wxShortcutManager(const wxShortcutManager& manager) { Init(); Copy(manager); }
    wxShortcutManager() { Init(); }
    ~wxShortcutManager() {}
    
    /// Copies the shortcuts
    void Copy(const wxShortcutManager& manager);

    /// Initialises the class
    void Init();

    /// Clears the items
    void Clear();

    /// Adds information about a shortcut
    void Add(const wxShortcutItem& info);

    /// Finds information about a shortcut
    wxShortcutItem* Find(const wxString& name) const;

    /// Finds the nth shortcut for the given name
    int FindIndex(const wxString& name) const;

    /// Finds a shortcut by id
    wxShortcutItem* FindById(int id) const;

    /// Gets the nth record
    wxShortcutItem* GetNth(int n) const;

    /// Gets the number of shortcuts
    int GetCount() const { return m_shortcuts.GetCount(); }

    /// Saves customisation to config
    virtual bool Save(wxConfigBase& config);

    /// Load customisation from config
    virtual bool Load(wxConfigBase& config);

    /// Save current state to original shortcut store
    virtual bool SaveOriginalShortcuts();

    /// Restore original shortcuts
    virtual bool ResetShortcuts();
    
    /// Make an accelerator table
    virtual wxAcceleratorTable MakeAcceleratorTable();
    
    /// Makes and sets the accelerator table into a particular window
    virtual bool SetAcceleratorTable(wxWindow* window);

    /// Updates labels with new accelerators
    virtual bool UpdateMenuBar(wxMenuBar* menuBar);

    /// Updates labels with new accelerators
    virtual bool UpdateMenu(wxMenu* menu);

    /// Returns the array of shortcuts
    wxShortcutItemArray& GetShortcuts() { return m_shortcuts; }

    /// Returns a human-readable string for the shortcut
    virtual wxString GetReadableShortcutString(const wxShortcutItem& item) const;
    
    /// Returns a shortcut string suitable for adding to menu item.
    virtual wxString GetMenuShortcutString(const wxShortcutItem& item) const;

    /// Is this a valid shortcut keycode?
    static bool IsValidShortcutKeyCode(int keycode);

    /// Return an array of all the shortcut items that have the given shortcut,
    /// except idException (if not -1).
    wxShortcutItemArray GetMatchingShortcuts(const wxShortcutItem& item, int idException = -1) const;
    
protected:

    wxShortcutItemArray m_shortcuts;
    wxShortcutItemArray m_originalShortcuts;
};

/**
 @class wxShortcutCtrl
 A text control for entering a shortcut (one part of the shortcut at a time).
*/

class wxShortcutCtrl: public wxTextCtrl
{
    DECLARE_DYNAMIC_CLASS(wxShortcutCtrl)
    DECLARE_EVENT_TABLE()

public:
    wxShortcutCtrl() { Init(); }

    wxShortcutCtrl(wxWindow* parent, wxWindowID id, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition,
        const wxSize& size = wxDefaultSize, int style = 0)
    {
        Init();
        Create(parent, id, value, pos, size, style);
    }
    bool Create(wxWindow* parent, wxWindowID id, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition,
        const wxSize& size = wxDefaultSize, int style = 0);

    void Init();

    void SetShortcut(const wxShortcutItem& item) { m_shortcut = item; }
    const wxShortcutItem& GetShortcut() const { return m_shortcut; }

    void OnKeyDown(wxKeyEvent& event);

    wxString GetShortcutString() const;
    
    void ApplyShortcut();

protected:

    wxShortcutItem  m_shortcut;
};

#endif
    // _WX_SHORTBARCUST_H_
